package com.xhorse.lockplatform.controller;

import com.xhorse.lockplatform.annotation.RequestLimit;
import com.xhorse.lockplatform.comm.constant.CommonResult;
import com.xhorse.lockplatform.comm.constant.ConstantString;
import com.xhorse.lockplatform.comm.constant.FilePathDefine;
import com.xhorse.lockplatform.comm.enums.ResultEnum;
import com.xhorse.lockplatform.comm.mvc.AbstractCallbackController;
import com.xhorse.lockplatform.comm.util.DateUtils;
import com.xhorse.lockplatform.comm.util.StringUtil;
import com.xhorse.lockplatform.model.XhKey;
import com.xhorse.lockplatform.model.XhModel;
import com.xhorse.lockplatform.model.XhUpdateInfo;
import com.xhorse.lockplatform.model.pojo.*;
import com.xhorse.lockplatform.service.ChipDataImportService;
import com.xhorse.lockplatform.service.KeyGeneratorService;
import com.xhorse.lockplatform.service.RenewDataImportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("Keyfunctions")
public class KeyGeneratorController extends AbstractCallbackController {

    @Autowired
    private KeyGeneratorService keyGeneratorService;

    @Autowired
    private RenewDataImportService renewDataImportService;

    @Autowired
    private ChipDataImportService chipDataImportService;

    /**
     * 版本检测
     *
     * @param httpServletRequest
     * @return
     */
    @RequestLimit(count = 1, time = 5000)
    @RequestMapping(value = "/DetectDataVersion", method = RequestMethod.POST)
    @ResponseBody
    public void DetectDataVersion(
            HttpServletRequest httpServletRequest, HttpServletResponse response) throws Exception {
        int regionId = Integer.valueOf(httpServletRequest
                .getParameter("regionId"));
        int languageId = Integer.valueOf(httpServletRequest
                .getParameter("languageId"));
        int imgVersion = keyGeneratorService.findImgVersion();
        int keyVersion = keyGeneratorService.findBrandVersion("0", languageId);
        int dataVersion = keyGeneratorService.findDataVersion("0", regionId);
        int remoteVersion = renewDataImportService.findMaxVersion("0", languageId);
        int chipVersion = chipDataImportService.findMaxVersion("0", languageId);
        Map<String, Integer> map = new HashMap<>();
        if (keyVersion != 0) {
            map.put("keyVersion", keyVersion);
        }
        if (imgVersion != 0) {
            map.put("imgVersion", imgVersion);
        }
        if (imgVersion != 0) {
            map.put("dataVersion", dataVersion);
        }
        if (remoteVersion != 0) {
            map.put("remoteVersion", remoteVersion);
        }
        if (chipVersion != 0) {
            map.put("chipVersion", chipVersion);
        }
        simpleSuccess(response, map);
    }

    /**
     * 遥控生成
     *
     * @param form
     * @param httpServletRequest
     * @param response
     */
    @RequestLimit(count = 1, time = 10000)
    @RequestMapping(value = "/KeyGenerate", method = RequestMethod.POST)
    @ResponseBody
    public void KeyGenerate(RequestForm form, HttpServletRequest httpServletRequest, HttpServletResponse response) throws Exception {
        String imgversion = form.getImgversion();
        String dbversion = form.getDbversion();
        int languageId = form.getLanguageId();
        int regionId = form.getRegionId();
        int makeType = form.getMakeType();
        if ((imgversion == null || imgversion.equals("0"))
                && dbversion.compareTo("222") > 0 && regionId != 8) {// 版本兼容部分，为国外用户矫正数据版本=============
            dbversion = "0";
        }
        // 获取增量更新数据
        int keyVersion = keyGeneratorService.findBrandVersion("0", languageId);
        if (keyVersion <= 0) {
            simpleFailed(response);
            return;
        }
        List<ResponseKeyInfo> list = new ArrayList<>();
        List<BrandInfo> brandList = keyGeneratorService.findBrand(dbversion, languageId);
        // 品牌信息
        for (BrandInfo brand : brandList) {
            XhModel xhModel = new XhModel();
            xhModel.setBrand_id(brand.getBrandId());
            xhModel.setLanguage_id(languageId);
            List<XhModel> modelList = keyGeneratorService.findModelByBrandId(xhModel);
            // 组装返回数据
            ResponseKeyInfo ResponseKeyInfo = new ResponseKeyInfo();
            ResponseKeyInfo.setLetter(brand.getLetter());
            List<CarMake> carMakeList = new ArrayList<>();
            List<CarModel> carModelList = new ArrayList<>();
            // 组装carMake数据
            CarMake carMake = new CarMake();
            carMake.setMakeId(brand.getBrandId());
            carMake.setMakeName(brand.getBrandName());
            // 型号信息
            for (XhModel model : modelList) {
                XhKey xhKey = new XhKey();
                xhKey.setModel_id(model.getModel_id());
                xhKey.setLanguage_id(languageId);
                xhKey.setRegion_id(regionId);
                xhKey.setMake_type(makeType);
                // 组装carModel数据
                CarModel carModel = new CarModel();
                carModel.setModelId(model.getModel_id());
                carModel.setModelName(model.getModel_name());
                carModel.setSort(model.getSort());
                // 组装key数据
                List<Vehicle> vehicleList = new ArrayList<>();
                List<XhKey> keyList = keyGeneratorService.findKeyByModelId(xhKey);
                // 钥匙信息
                for (XhKey key : keyList) {
                    Vehicle vehicle = new Vehicle();
                    vehicle.setKeyId(key.getKey_id());
                    vehicle.setFileId(key.getFile_id());
                    vehicle.setHcsId(key.getHcs_algo_id());
                    vehicle.setMatchMethod(key.getMatch_method());
                    vehicle.setType(key.getType());
                    vehicle.setVehicle(key.getKey_name());
                    vehicle.setVehicleId(key.getVehicle_id());
                    vehicle.setUpdateAt(null);
                    vehicle.setUpdateTime(DateUtils.dateToString(key.getUpdate_at(), DateUtils.DATE_PATTERN));
                    vehicle.setFeatureString(appendStr(vehicle));
                    vehicleList.add(vehicle);
                }
                if (!vehicleList.isEmpty()) {
                    carModel.setVehicleList(vehicleList);
                    carModelList.add(carModel);
                }
            }
            if (!carModelList.isEmpty()) {
                carMake.setCarmodelList(carModelList);
                carMakeList.add(carMake);
                ResponseKeyInfo.setCarmakeList(carMakeList);
                list.add(ResponseKeyInfo);
            }
        }
        simpleSuccess(response, list);
    }

    /**
     * 遥控生成的图片，文件下载
     *
     * @param request
     * @param response
     */
    @RequestLimit(count = 1, time = 10000)
    @RequestMapping(value = "zipdownload", method = RequestMethod.POST)
    @ResponseBody
    public void zipdownload(RequestForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String imgversion = form.getImgversion();
        String dbversion = form.getDbversion();
        int languageId = form.getLanguageId();
        int regionId = form.getRegionId();
        Long downloaded = Long.valueOf(0);
        if (StringUtil.isNotNil(form.getDownloaded())) {
            downloaded = Long.valueOf(form.getDownloaded());
        }
        if ((imgversion == null || imgversion.equals("0")) && regionId != 8
                && dbversion.compareTo("221") > 0) { // 版本兼容部分，为国外用户矫正数据版本==================================
            dbversion = "0";
            imgversion = "0";
        }
        if ((imgversion == null || imgversion.equals("0")) && regionId == 8) {
            imgversion = dbversion;
        }
        // 获取当前库的最大版本号
        String newVersion = String.valueOf(keyGeneratorService.findBrandVersion(dbversion, languageId));
        // 获取图片版本号
        String imgVersion = String.valueOf(keyGeneratorService.findImgVersion());
        if (newVersion == null) {
            newVersion = dbversion;
        }
        if (imgVersion == null) {
            imgVersion = imgversion;
        }
        response.addHeader("dbversion", newVersion);
        response.addHeader("imgversion", imgVersion);
        String filePath;
        if (newVersion == null) {
            simpleFailed(response, ResultEnum.CRUD_NEW_VERSION.getMsg());
        } else {
            if (dbversion.equals("0")) {
                filePath = FilePathDefine.KEYGENERATE + regionId + ".zip";
            } else {
                filePath = FilePathDefine.KEYGENERATE + dbversion + "-"
                        + newVersion + "-" + regionId + ".zip";
                File temp = new File(filePath);
                if (!temp.exists()) {
                    keyGeneratorService.generateZipFile(imgversion, dbversion,
                            newVersion, regionId);
                }
            }
            File file = new File(filePath);
            if (file.exists()) {
                response.setContentLength(new Long(file.length()).intValue()); // 设置响应头:文件大小
                // 打开本地文件流
                RandomAccessFile randomAccessFile = new RandomAccessFile(
                        filePath, "r");
                randomAccessFile.seek(downloaded);
                // 激活下载操作
                OutputStream outputStream = response.getOutputStream();
                // 循环写入输出流
                byte[] b = new byte[1024];
                int length;
                while ((length = randomAccessFile.read(b)) != -1) {
                    outputStream.write(b, 0, length);
                }
                // 关闭流
                outputStream.close();
                randomAccessFile.close();
            }
        }
    }

    /**
     * 钥匙解锁数据获取
     *
     * @param dbversion
     * @param languageId
     * @return
     */
    @RequestLimit(count = 1, time = 10000)
    @RequestMapping(value = "remoteInfoGenerate")
    @ResponseBody
    public void remoteInfoGenerate(HttpServletRequest request, HttpServletResponse response, String dbversion, int languageId) throws Exception {
        int maxVersion = renewDataImportService.findMaxVersion(dbversion, languageId);
        List<CarMake> carMakes = keyGeneratorService.remoteInfoGenerate(dbversion, languageId);
        ResponseRemoteInfo remoteInfo = new ResponseRemoteInfo();
        if (!carMakes.isEmpty()) {
            remoteInfo.setMake_logo_url(ConstantString.IP + "XhorseConnector/images/renew/makeImage/");
            remoteInfo.setAdapter_url(ConstantString.IP + "XhorseConnector/images/renew/adapterImage/");
            remoteInfo.setPcb_url(ConstantString.IP + "XhorseConnector/images/renew/pcbImage/");
            remoteInfo.setSurface_url(ConstantString.IP + "XhorseConnector/images/renew/surfaceImage/");
        }
        remoteInfo.setCarMakes(carMakes);
        simpleSuccess(response, remoteInfo);
    }

    /**
     * 芯片生成
     *
     * @param dbversion
     * @param languageId
     * @return
     */
    @RequestLimit(count = 1, time = 10000)
    @RequestMapping(value = "chipGenerate")
    @ResponseBody
    public void chipGenerate(HttpServletRequest request, HttpServletResponse response, String dbversion, int languageId) throws Exception {
        int maxVersion = chipDataImportService.findMaxVersion(dbversion, languageId);
        List<ResponseKeyInfo> xhChips = keyGeneratorService.chipGenerate(dbversion, languageId);
        simpleSuccess(response, xhChips);
    }


    /**
     * 获取更新日志
     *
     * @return
     */
    @RequestMapping(value = "getUpdateLog", method = RequestMethod.POST)
    @ResponseBody
    public void getUpdateLog(HttpServletRequest request, HttpServletResponse response, int regionId, int languageId) throws Exception {
        List<XhUpdateInfo> xhUpdateInfos = keyGeneratorService
                .selectLogByVersion(regionId, languageId);
        if (!xhUpdateInfos.isEmpty()) {
            simpleSuccess(response, xhUpdateInfos);
        } else {
            simpleFailed(response, ResultEnum.CRUD_NOT_DATA.getMsg());
        }
    }

    /**
     * 组装标签字符串
     *
     * @return
     */
    private String appendStr(Vehicle vehicle) {
        StringBuilder stringBuilder = new StringBuilder();
        if (vehicle.getBlank() != null
                && !vehicle.getBlank().equals("")) {
            stringBuilder.append(vehicle.getBlank())
                    .append("#&");
        }
        if (vehicle.getFccid() != null
                && !vehicle.getFccid().equals("")) {
            stringBuilder.append(vehicle.getFccid())
                    .append("#&");
        }
        if (vehicle.getFreq() != null
                && !vehicle.getFreq().equals("")) {
            stringBuilder.append(vehicle.getFreq()).append(
                    "#&");
        }
        if (vehicle.getEncode() != null
                && !vehicle.getEncode().equals("")) {
            stringBuilder.append(vehicle.getEncode())
                    .append("#&");
        }
        if (vehicle.getTypeName() != null
                && !vehicle.getTypeName().equals("")) {
            stringBuilder.append(vehicle.getTypeName())
                    .append("#&");
        }
        if (vehicle.getHcsId() != null
                && !vehicle.getHcsId().equals("")) {
            stringBuilder.append(vehicle.getHcsId())
                    .append("#&");
        }
        if (vehicle.getEepalgId() != null
                && !vehicle.getEepalgId().equals("")) {
            stringBuilder.append(vehicle.getEepalgId())
                    .append("#&");
        }
        if (vehicle.getChipTypeNumber() != null
                && !vehicle.getChipTypeNumber().equals("")) {
            stringBuilder.append(
                    vehicle.getChipTypeNumber()).append(
                    "#&");
        }
        if (vehicle.getKnownAsId() != null
                && !vehicle.getKnownAsId().equals("")) {
            stringBuilder.append(vehicle.getKnownAsId())
                    .append("#&");
        }
        if (vehicle.getReplacePartNumber() != null
                && !vehicle.getReplacePartNumber().equals(
                "")) {
            stringBuilder.append(
                    vehicle.getReplacePartNumber()).append(
                    "#&");
        }
        if (vehicle.getOtherPartNo() != null
                && !vehicle.getOtherPartNo().equals("")) {
            stringBuilder.append(vehicle.getOtherPartNo())
                    .append("#&");
        }
        if (vehicle.getCloneableRemote() != null
                && !vehicle.getCloneableRemote().equals("")) {
            stringBuilder.append(
                    vehicle.getCloneableRemote()).append(
                    "#&");
        }
        if (vehicle.getCloneableChip() != null
                && !vehicle.getCloneableChip().equals("")) {
            stringBuilder
                    .append(vehicle.getCloneableChip())
                    .append("#&");
        }
        return stringBuilder.toString();
    }

    public static class RequestForm {
        private String dbversion;
        private String imgversion;
        private int languageId;
        private int regionId;
        private int makeType;
        private String downloaded;

        public String getDbversion() {
            return dbversion;
        }

        public void setDbversion(String dbversion) {
            this.dbversion = dbversion;
        }

        public String getImgversion() {
            return imgversion;
        }

        public void setImgversion(String imgversion) {
            this.imgversion = imgversion;
        }

        public int getLanguageId() {
            return languageId;
        }

        public void setLanguageId(int languageId) {
            this.languageId = languageId;
        }

        public int getRegionId() {
            return regionId;
        }

        public void setRegionId(int regionId) {
            this.regionId = regionId;
        }

        public int getMakeType() {
            return makeType;
        }

        public void setMakeType(int makeType) {
            this.makeType = makeType;
        }

        public String getDownloaded() {
            return downloaded;
        }

        public void setDownloaded(String downloaded) {
            this.downloaded = downloaded;
        }

        @Override
        public String toString() {
            return "RequestForm{" +
                    "dbversion='" + dbversion + '\'' +
                    ", imgversion='" + imgversion + '\'' +
                    ", languageId=" + languageId +
                    ", regionId=" + regionId +
                    ", makeType=" + makeType +
                    ", downloaded='" + downloaded + '\'' +
                    '}';
        }
    }

    public static class ResponseRemoteInfo {
        private String make_logo_url;
        private String adapter_url;
        private String pcb_url;
        private String surface_url;
        private List<CarMake> carMakes;

        public String getMake_logo_url() {
            return make_logo_url;
        }

        public void setMake_logo_url(String make_logo_url) {
            this.make_logo_url = make_logo_url;
        }

        public String getAdapter_url() {
            return adapter_url;
        }

        public void setAdapter_url(String adapter_url) {
            this.adapter_url = adapter_url;
        }

        public String getPcb_url() {
            return pcb_url;
        }

        public void setPcb_url(String pcb_url) {
            this.pcb_url = pcb_url;
        }

        public String getSurface_url() {
            return surface_url;
        }

        public void setSurface_url(String surface_url) {
            this.surface_url = surface_url;
        }

        public List<CarMake> getCarMakes() {
            return carMakes;
        }

        public void setCarMakes(List<CarMake> carMakes) {
            this.carMakes = carMakes;
        }
    }
}